#include "StdAfx.h"
#include <atlenc.h>
#include "Base64.h"

namespace PPLiveLogClient
{

Base64::Base64(void)
{
}

Base64::~Base64(void)
{
}

CStringA Base64::Encode(const SimpleBinaryData& data, bool noTailPadding/*=false*/) const
{
	CStringA result;
	int bufferBytes = data.DataBytes() * 2; // enough for base64 encoding;
	PSTR p = result.GetBuffer(data.DataBytes() * 2);
	DWORD flags = ATL_BASE64_FLAG_NOCRLF;
	if (noTailPadding)
	{
		flags |= ATL_BASE64_FLAG_NOPAD;
	}
	ATL::Base64Encode(data.Data(), data.DataBytes(), p, &bufferBytes, flags);
	result.ReleaseBuffer(bufferBytes); // bufferBytes change to actual data length after calling Base64Encode()

	return result;
}

CStringA Base64::UrlFriendlyEncode(const SimpleBinaryData& data, bool noTailPadding/*=false*/) const
{
	CStringA result = Encode(data, noTailPadding);
	// RFC 4648 latest Base64 Standard http://tools.ietf.org/html/rfc4648#page-7
	// ATL doesn't provide such support, so here just work on encoded data, scan and replace.
	// in extreme scenario there may be performance issue, but should be enough for most running.
	result.Replace('+', '-');
	result.Replace('/', '_');
	return result;
}

}